/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package lcfgly.database;

import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import javax.sql.DataSource;
import lcfgly.database.utils.LDecodeObject;
import lcfgly.database.utils.LSelectDecode;
import lcfgly.utils.LTypeUtils;

/**
 * LDMysqlExt
 * @author lcfgly
 * @Date 2015-1-29 14:37:45
 * @version 1.0
 */
public class LDMysqlExt extends LDMysql implements LIDatabaseExt{
    
    LDecodeObject decodeObject=new LDecodeObject();
    
    public LDMysqlExt(DataSource ds) {
        super(ds);
    }

    @Override
    public <T> T one(Class<T> cs, String where, Object... args) throws LSqlException {
        String sql=decodeObject.selectString(cs);
        if(!LTypeUtils.stringIsEmpty(where))
            sql+=where+" ";
        if(Pattern.matches("(?i)(.*?) LIMIT (.*?)(\\s.*)?", sql)){
            sql=sql.replace("(?i)(.*?) LIMIT (.*?)(\\s.*)?", "$1 LIMIT 1 $3");
        }else{
            sql+=sql+" limit 1 ";
        }
        Map<String,Object> rs=super.one(sql, args);
        return decodeObject.setObject(cs, rs);
    }

    @Override
    public <T> List<T> rows(Class<T> cs, String where, Object... args) throws LSqlException {
        String sql=decodeObject.selectString(cs);
        if(!LTypeUtils.stringIsEmpty(where))
            sql+=where;
        List<Map<String,Object>> rss=super.rows(sql, args);
        List<T> result=new LinkedList<>();
        for (Map<String, Object> rs : rss) {
            result.add(decodeObject.setObject(cs, rs));
        }
        return result;
    }

    @Override
    public boolean updateObject(Object ob) throws LSqlException {
        Object[] rs=decodeObject.updateString(ob);
        String sql=rs[0].toString();
        LinkedList<Object> args=(LinkedList<Object>)rs[1];
        String swhere=rs[2].toString();
        Object owhere=rs[3];
        sql+=swhere;
        args.add(owhere);
        super.updateSql(sql, args.toArray());
        return true;
    }

    @Override
    public boolean insertObject(Object ob) throws LSqlException {
        Object[] rs=decodeObject.insertString(ob);
        String sql=rs[0].toString();
        LinkedList<Object> args=(LinkedList<Object>)rs[1];
        return super.insert(sql, args.toArray());
    }

    @Override
    public int insertObjectBackId(Object ob) throws LSqlException {
        Object[] rs=decodeObject.insertString(ob);
        String sql=rs[0].toString();
        LinkedList<Object> args=(LinkedList<Object>)rs[1];
        return super.insertBackId(sql, args.toArray());
    }

    @Override
    public boolean deleteObject(Object ob) throws LSqlException {
        Object[] rs=decodeObject.deleteString(ob);
        String sql=rs[0].toString();
        LinkedList<Object> args=(LinkedList<Object>)rs[1];
        super.deleteSql(sql, args.toArray());
        return true;
    }

    @Override
    public boolean updateObject(Object ob, String where, Object... args)throws LSqlException {
        Object[] rs=decodeObject.updateString(ob);
        String sql=rs[0].toString();
        LinkedList<Object> pargs=(LinkedList<Object>)rs[1];
        if(LTypeUtils.stringIsEmpty(where))
        {
            sql+=rs[2].toString();
            pargs.add(rs[3]);
        }else{
            sql+=where;
            if(args != null)
                pargs.addAll(Arrays.asList(args));
        }
        super.updateSql(sql, pargs.toArray());
        return true;
    }

    @Override
    public void setPrefix(String prefix) {
        decodeObject.setPrefix(prefix);
    }

    @Override
    public String getPrefix() {
        return decodeObject.getPrefix();
    }

    @Override
    public Map Page(String sql, int page, int pagecount, Object... args)throws LSqlException {
        Integer rowsnum = count(sql, args);
        Map result=new HashMap();
        result.put("rows", rowsnum);
         if(rowsnum == 0){
             result.put("data", null);
         }else{
            int pagenum=rowsnum/pagecount;
            page=(page-=1)<0?0:page;
            page=page>pagenum?pagenum:page;
            LSelectDecode ls=new LSelectDecode(sql, decodeObject.getPrefix());
            StringBuilder limit=ls.getLimit();
            limit.setLength(0);
            limit.append(page*pagecount+","+pagecount);
            result.put("data", rows(ls.Sql(), args));
         }
         return result;
    }
    
}